package com.excel.analysis;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;

public class Analysis {

	private String path = null;

	private Document document = null;

	private Element root = null;

	private List<ExcelRow> beans = null;

	private List<ExcelBean> kpi = null;

	private Map<String, List<Map<String, String>>> parameters = new HashMap<String, List<Map<String, String>>>();

	private int contractId;

	/**
	 * 构造函数
	 * 
	 * @param path
	 * @throws Exception
	 */
	public Analysis(String path, int index) throws Exception {
		this.path = path;
		document = DocumentHelper.createDocument();
		document.addProcessingInstruction("xml-stylesheet", "type='text/xsl' href='template/htmlTemplate.xsl'");
		root = document.addElement("template");
		ReaderExcel excelReader = new ReaderExcel(path);
		beans = excelReader.analysis(index);
		kpi = excelReader.getKpi();
	}

	/**
	 * 生成XML
	 * 
	 * @throws Exception
	 */
	public void analysisXml() throws Exception {
		if (beans == null) {
			throw new Exception("beans is null");
		}
		for (int i = 0; i < beans.size();) {
			ExcelRow bean = beans.get(i);
			String value = bean.getValue();
			if (value != null && ExpressionUtils.isHeader(value)) {
				// 处理header
				Element header = root.addElement("page-header");
				i = handlerHeader(header, i + 1);
			} else if (value != null && ExpressionUtils.isUserDefine(value)) {
				// 处理user-defined
				Element userDefined = root.addElement("user-defined");
				i = handlerUserDefine(userDefined, i + 1);
			} else if (value != null && ExpressionUtils.isFooter(value)) {
				// 处理footer
				Element footer = root.addElement("page-footer");
				i = handlerFooter(footer, i + 1);
			} else if (value != null && ExpressionUtils.isCPQ(value)) {
				// 处理cpq
				Element cpq = root.addElement("cpq");
				i = handlerCpq(cpq, i + 1);
				handlerKpi(cpq, kpi, null);
			} else {
				i++;
			}
		}
	}

	/**
	 * 生成指标
	 * 
	 * @param cpq
	 * @throws Exception
	 */
	public void handlerKpi(Element cpq, List<ExcelBean> list, String preffix) throws Exception {
		int k = 1;
		for (ExcelBean b : list) {
			if (b != null && ExpressionUtils.isKpi(b.getValue())) {
				String code = null;
				if(preffix != null) {					
					code = preffix + GsonUtils.createCode(k);
				} else {
					code = GsonUtils.createCode(k);
				}
				Element kpi = cpq.addElement("kpi");
				kpi.addAttribute("level", b.getJsonValue("level"));
				kpi.addAttribute("source", b.getJsonValue("source"));
				kpi.addAttribute("score", "0");
				kpi.addAttribute("norm-score", "0");
				String _code = b.getJsonValue("code");
				if(_code != null) {
					code = _code;
				}
				kpi.addAttribute("code", code);
				b.setCode(code);
				Element name = kpi.addElement("name");
				name.addCDATA(b.getJsonValue("kpi"));
				handlerKpi(kpi, b.getBeans(), code);
				k++;
			} else if (b != null && ExpressionUtils.isEntry(b.getValue())) {
				Element kpi = cpq.addElement("entry");
				kpi.addAttribute("id", this.getContractId());
				kpi.addAttribute("source", b.getJsonValue("source"));
				kpi.addAttribute("type", b.getJsonValue("type"));
				kpi.addAttribute("score", "0");
				kpi.addAttribute("norm-score", "0");
				kpi.addAttribute("scoring-rules", b.getJsonValue("rules"));
				String use = b.getJsonValue("use");
				if(use != null) {
					kpi.addAttribute("use", use);
				}
				Element name = kpi.addElement("name");
				name.addCDATA(b.getJsonValue("entry"));
				// 问题选项
				JsonArray jsonArray = b.getJson("dataArray");
				if (jsonArray != null && jsonArray.size() > 0) {
					for (int i = 0; i < jsonArray.size(); i++) {
						JsonObject je = jsonArray.get(i).getAsJsonObject();
						Element item = kpi.addElement("item");
						item.addAttribute("id", getContractId());
						item.addAttribute("selected", "n");
						// 分数属性
						JsonElement j = je.get("source");
						if (j != null) {
							item.addAttribute("source", j.getAsString());
						}
						// 条目
						j = je.get("name");
						if (j != null) {
							Element c = item.addElement("content");
							c.addCDATA(j.getAsString());
						}
					}
				}
			}
		}
	}

	/**
	 * 指标处理
	 * 
	 * @param cpq
	 * @param start
	 * @return
	 * @throws Exception
	 */
	public int handlerCpq(Element cpq, int start) throws Exception {
		int i = start;
		for (; i < beans.size();) {
			ExcelRow eb = beans.get(i);
			String value = eb.getValue();
			if (value != null && ExpressionUtils.isEndCPQ(value)) {
				i++;
				break;
			}
			if (ExpressionUtils.isTitleBar(value)) {
				// cpq标题
				Element ts = cpq.addElement("titles");
				ExcelRow e = beans.get(++i);
				for (int k = 0; k < e.getBeans().size(); k++) {
					ExcelBean b = e.getBeans().get(k);
					Element t = ts.addElement("title");
					t.addAttribute("rowspan", b.rowspan());
					t.addAttribute("colspan", b.colspan());
					t.addCDATA(b.getValue());
				}
			} else if (ExpressionUtils.isCpqArea(value)) {
				i = handlerCqpArea(i + 1);
			} else {
				i++;
			}
		}
		return i;
	}

	/**
	 * 一级指标处理
	 * 
	 * @param cpq
	 * @param start
	 * @return
	 * @throws Exception
	 */
	public int handlerCqpArea(int startRow) throws Exception {
		int i = startRow;
		for (; i < beans.size();) {
			ExcelRow r = beans.get(i); // 获取行
			ExcelBean eb = r.getBeans().get(0); // 获得第一行
			String value = eb.getValue();
			if (ExpressionUtils.isEndCpqArea(value)) {
				i++;
				break;
			} else if (ExpressionUtils.isKpi(value)) {
				i = eb.getEndRow() + 1;
			} else {
				i++;
			}
		}
		return i;
	}

	/**
	 * 处理footer部分
	 * 
	 * @param userDefine
	 * @param start
	 * @return
	 */
	public int handlerFooter(Element userDefine, int start) {
		int i = start;
		for (; i < beans.size();) {
			ExcelRow eb = beans.get(i);
			String value = eb.getValue();
			if (value != null && ExpressionUtils.isEndFooter(value)) {
				i++;
				break;
			}
			Element row = userDefine.addElement("row");
			for (int j = 0; j < eb.getBeans().size(); j++) {
				ExcelBean bean = eb.getBeans().get(j);
				Element col = row.addElement("column");
				col.addAttribute("rowspan", bean.rowspan());
				col.addAttribute("colspan", bean.colspan());
				if (bean.getValue() == null) {
					// 标签
					Element e = col.addElement("control");
					e.addAttribute("type", "label");
				} else if (bean.getValue() != null
						&& !ExpressionUtils.isField(bean.getValue())) {
					// 标签
					Element e = col.addElement("control");
					e.addAttribute("type", "label");
					e.addCDATA(bean.getValue());
				} else {
					// 控件
					Element e = col.addElement("control");
					e.addAttribute("id", this.getContractId());
					e.addAttribute("field", bean.getJsonValue("field"));
					String type = bean.getJsonValue("type");
					e.addAttribute("type", bean.getJsonValue("type"));
					if (type.equals("select") || type.equals("radio")
							|| type.equals("checkbox")) {
						// 设置的数据
						List<String> list = bean.getJsonValues("dataArray");
						if (list != null && list.size() > 0) {
							for (int k = 0; k < list.size(); k++) {
								Element item = e.addElement("item");
								item.addAttribute("id", getContractId());
								item.addAttribute("selected", "n");
								item.addCDATA(list.get(k));
							}
						} else {
							// 引用数据
							String ref = bean.getJsonValue("ref");
							// 如果dataArray不存在，是否含有ref属性
							if (ref != null && !ref.equals("")) {
								e.addAttribute("ref", ref);
							}
							// TODO 找到变量生成XML
						}
					} else if (type.equals("button")) {
						String _value = bean.getJsonValue("value");
						if (_value != null && !_value.equals("")) {
							e.addAttribute("value", _value);
						} else {
							e.addAttribute("value", "");
						}
					} else {
						e.addElement("content");
					}
				}
			}
			i++;
		}
		return i;
	}

	/**
	 * 处理自定义部分
	 * 
	 * @param userDefine
	 * @param start
	 * @return
	 */
	public int handlerUserDefine(Element userDefine, int start) {
		int i = start;
		for (; i < beans.size();) {
			ExcelRow eb = beans.get(i);
			String value = eb.getValue();
			if (value != null && ExpressionUtils.isEndUserDefine(value)) {
				i++;
				break;
			}
			Element row = userDefine.addElement("row");
			for (int j = 0; j < eb.getBeans().size(); j++) {
				ExcelBean bean = eb.getBeans().get(j);
				Element col = row.addElement("column");
				col.addAttribute("rowspan", bean.rowspan());
				col.addAttribute("colspan", bean.colspan());
				if (!ExpressionUtils.isField(bean.getValue())) {
					// 标签
					Element e = col.addElement("control");
					e.addAttribute("type", "label");
					e.addCDATA(bean.getValue());
				} else {
					// 控件
					Element e = col.addElement("control");
					String field = bean.getJsonValue("field");
					e.addAttribute("id", this.getContractId());
					e.addAttribute("field", field);
					String type = bean.getJsonValue("type");
					e.addAttribute("type", bean.getJsonValue("type"));
					if (type.equals("select") || type.equals("radio")
							|| type.equals("checkbox")) {
						// 设置的数据
						List<String> list = bean.getJsonValues("dataArray");
						if (list != null && list.size() > 0) {
							for (int k = 0; k < list.size(); k++) {
								Element item = e.addElement("item");
								item.addAttribute("id", getContractId());
								item.addAttribute("selected", "n");
								item.addCDATA(list.get(k));
							}
						} else {
							// 引用数据
							String ref = bean.getJsonValue("ref");
							// 如果dataArray不存在，是否含有ref属性
							if (ref != null && !ref.equals("")) {
								e.addAttribute("ref", ref);
							}
							// 变量生成XML
							List<Map<String, String>> param = parameters
									.get(ref);
							if (param != null && !param.isEmpty()) {
								for (Map<String, String> m : param) {
									Element item = e.addElement("item");
									item.addAttribute("id", getContractId());
									item.addAttribute("selected", "n");
									Iterator<String> keys = m.keySet()
											.iterator();
									while (keys.hasNext()) {
										String key = keys.next();
										String _value = m.get(key);
										item.addAttribute(key, _value);
										if (key.equals(field)) {
											item.addCDATA(_value);
										}
									}
								}
							}
						}
					} else if (type.equals("button")) {
						String _value = bean.getJsonValue("value");
						if (_value != null && !_value.equals("")) {
							e.addAttribute("value", _value);
						} else {
							e.addAttribute("value", "");
						}
					} else {
						e.addElement("content");
					}
				}
			}
			i++;
		}
		return i;
	}

	/**
	 * 处理page-header
	 * 
	 * @param header
	 * @param start
	 * @return
	 * @throws Exception
	 */
	public int handlerHeader(Element header, int start) throws Exception {
		int i = start;
		Element vars = null;
		for (; i < beans.size();) {
			ExcelRow bean = beans.get(i);
			String value = bean.getValue();
			if (ExpressionUtils.isEndHeader(value)) {
				i++;
				break;
			} else if (ExpressionUtils.isHeaderLabel(value)) {
				ExcelBean eb = bean.getBeans().get(0);
				Element e = header.addElement("label");
				e.addCDATA(eb.getJsonValue("label"));
				e.addAttribute("colspan", eb.colspan());
				e.addAttribute("rowspan", eb.rowspan());
				i++;
			} else if (ExpressionUtils.isHeaderVar(value)) {
				// 变量集合定义
				if (vars == null) {
					vars = header.addElement("vars");
				}
				Element v = vars.addElement("var");
				String _v = bean.getJsonValue("vars");
				List<Map<String, String>> m = new ArrayList<Map<String, String>>();
				parameters.put(_v, m);
				// 元素
				v.addAttribute("name", bean.getJsonValue("vars"));
				v.addAttribute("type", bean.getJsonValue("type"));
				List<String> headers = new ArrayList<String>();
				if (bean.getJsonValue("type") != null
						&& bean.getJsonValue("type").equals("collection")) {
					Element titles = v.addElement("titles");
					// 变量集合,获得下一行，并设置变量列头
					bean = beans.get(++i);
					for (int j = 0; j < bean.getBeans().size(); j++) {
						ExcelBean eb = bean.getBeans().get(j);
						Element title = titles.addElement("title");
						title.addAttribute("name", eb.getJsonValue("field"));
						title.addAttribute("value", eb.getJsonValue("value"));
						headers.add(eb.getJsonValue("field"));
					}
					// 处理集合变量参数
					i = handlerParameters(headers, i + 1, v, m);
				} else {
					i++;
				}
			} else {
				i++;
			}
		}
		return i;
	}

	/**
	 * header头部，参数集合处理
	 * 
	 * @param list
	 * @param start
	 * @param element
	 * @return
	 * @throws Exception
	 */
	public int handlerParameters(List<String> list, int start, Element element,
			List<Map<String, String>> m) throws Exception {
		Element attrs = element.addElement("attributes");
		int i = start;
		for (; i < beans.size();) {

			ExcelRow eb = beans.get(i);
			String value = eb.getValue();
			if (ExpressionUtils.isHeaderEndVar(value)) {
				i++;
				break;
			} else {
				Map<String, String> p = new HashMap<String, String>();
				Element attr = attrs.addElement("attr");
				for (int j = 0; j < eb.getBeans().size(); j++) {
					ExcelBean _eb = eb.getBeans().get(j);
					attr.addAttribute(list.get(j), _eb.getValue());
					p.put(list.get(j), _eb.getValue());
				}
				m.add(p);
				i++;
			}
		}
		return i;
	}

	/**
	 * 输出XML
	 * 
	 * @return
	 */
	public String toXml() {
		return document.asXML();
	}

	public List<ExcelBean> getKpi() {
		return kpi;
	}

	public String getContractId() {
		return String.valueOf(++contractId);
	}

	public Document getDocument() {
		return document;
	}

	public Map<String, List<Map<String, String>>> getParameters() {
		return parameters;
	}

	public String getPath() {
		return path;
	}

}
